<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <h2>compile</h2>
      <p>{{ name }}</p>
      <p>{{ age }}</p>
    </div>
    <button onclick="fn()">btn</button>
  </body>

  <script>
    const data = {
      name: "zhangsan",
      age: 20,
    };

    const str = document.querySelector("#app").innerHTML;
    console.log(str);

    // compile函数就是将变量渲染到html里面
    const compile = (node) => {
      // node.children可以拿到里面的node节点(伪数组)
      // console.log(node.children);
      // 可以通过扩展运算符或者Array.from()方法转成真正的数组
      const children = [...node.children];
      // 验证双大括号的正则表达式
      const reg = /\{\{(.*)\}\}/;
      children.forEach((child) => {
        // 查看内容里面是否有双大括号
        if (reg.test(child.textContent)) {
          // RegExp.$1表示的是匹配到的第一个内容
          child.innerHTML = data[RegExp.$1.trim()];
        }
      });
    };
    compile(document.querySelector("#app"));

    const observer = (data, prop, value) => {
      Object.defineProperty(data, prop, {
        get() {
          return value;
        },
        set(v) {
          // 可以在set函数里面知道数据什么时候被修改的
          // 那么就可以在这里去调用渲染函数，让页面重新渲染
          console.log(prop + "的值从" + value + "变成了" + v);

          value = v;

          document.querySelector("#app").innerHTML = str;
          compile(document.querySelector("#app"));
        },
      });
    };

    // ["name", "age"]
    Object.keys(data).forEach((item) => {
      observer(data, item, data[item]);
    });

    setTimeout(() => {
      data.name = "lisi";
    }, 2000);

    const fn = () => {
      data.age = 100;
    };
  </script>
</html>
